<template>
  <div ref="propertyPanel" class="property-panel">
    <div v-if="elementName" class="title">{{ elementName }}</div>
    <component
      ref="_component"
      :is="getComponent"
      v-if="element"
      :modelData="modelData"
      :element="element"
      :modeler="modeler"
      :key="`${curVersion}_${element.id}`"
    />
  </div>
</template>

<script>
import bpmnNode from './BpmnNode'
import bpmnProcess from './BpmnProcess'
import lodash from 'lodash'
import { NodeName } from '../translate/lang/zh'
import { getHmmodelfolderListTree } from '@/apis/paas/HmModelFolderController.js'

export default {
  name: 'Element',
  components: {
    bpmnProcess,
    bpmnNode
  },
  props: {
    modeler: {
      type: Object,
      required: true
    },
    modelData: {
      type: Object,
      required: true
    },
    curVersion: {
      type: Number,
      default: 0
    }
  },
  data () {
    return {
      element: null,
      errorTab: null,
      form: {
        id: '',
        name: '',
        color: null
      },
      modelPromise: Promise.resolve({})
    }
  },
  computed: {
    getComponent () {
      const type = this.element?.type
      if (type === 'bpmn:Process') {
        return 'bpmnProcess'
      } else {
        return 'bpmnNode'
      }
      // return null
    },
    elementName () {
      if (this.element) {
        if (this.element.id === '__initiator__') {
          return '提交节点'
        } else if (this.element.id.startsWith('Script_')) {
          return '脚本任务'
        }
        const bizObj = this.element.businessObject
        const type = bizObj?.eventDefinitions
          ? bizObj.eventDefinitions[0].$type
          : bizObj.$type
        return NodeName[type] || type
      }
      return ''
    }
  },

  created () {
    this.modelPromise = this.loadModels()
  },

  mounted () {
    this.handleModeler()
  },
  methods: {
    handleModeler () {
      this.modeler.on('shape.added', e => {
        if (e.element.type === 'bpmn:UserTask' && e.element.id !== '__initiator__') {
          // 用户节点增加默认任务监听 需要判断已经添加过
          let extensionElements = e.element.businessObject.get('extensionElements')
          if (extensionElements?.values.find(value => value.$type === 'flowable:TaskListener')) {
            return
          }
          if (!extensionElements) {
            extensionElements = this.modeler.get('moddle').create('bpmn:ExtensionElements')
          }
          // 移除taskListener
          // const listener = this.modeler.get('moddle').create('flowable:TaskListener')
          // listener['event'] = 'create'
          // /* eslint-disable no-template-curly-in-string */
          // listener['delegateExpression'] = '${userTaskCreationListener}'
          // extensionElements.get('values').push(listener)
          this.$nextTick(() => {
            this.modeler.get('modeling').updateProperties(e.element, {
              extensionElements
            })
          })
        } else if (e.element.type === 'bpmn:EndEvent' && !e.element.name) {
          // 默认结束节点名称 “结束”
          this.$nextTick(() => {
            this.modeler.get('modeling').updateLabel(e.element, '结束')
          })
        } else if (e.element.type === 'bpmn:ServiceTask' && e.element._dataAction === 'create.service-script-task') {
          // 创建脚本节点的时候需要更新id为Script_
          this.$nextTick(() => {
            this.modeler.get('modeling').updateProperties(e.element, {
              id: e.element.id.replace('Activity_', 'Script_')
            })
          })
        }
      })

      this.modeler.on('element.click', e => {
        const { element } = e
        if (element.type === 'bpmn:Process') {
          this.element = element
          this.$store.commit('SET_RIGHT_ASIDE_VISIBLE', false)
        }
      })

      this.modeler.on('selection.changed', e => {
        const element = e.newSelection[0]
        if (element) {
          this.element = element
          this.$store.commit('SET_RIGHT_ASIDE_VISIBLE', true)
        }
      })
    },

    /**
     * 全局校验以后定位到当前节点
     * 并触发form校验
     */
    // triggerElementChange (element) {
    //   this.element = element
    //   this.$store.commit('SET_RIGHT_ASIDE_VISIBLE', true)
    //   this.$nextTick(() => {
    //     this.validate()
    //   })
    // },

    handleGlobalSetting () {
      const elementRegistry = this.modeler.get('elementRegistry')
      const processElement = elementRegistry.filter((item) => item.type === 'bpmn:Process')[0]
      this.element = processElement
      this.$store.commit('SET_RIGHT_ASIDE_VISIBLE', true)
    },

    validate (errorTab) {
      this.$refs._component && (this.$refs._component.errorTab = errorTab)
      return this.$refs._component?.validate()
    },

    async loadModels () {
      const res = await getHmmodelfolderListTree()
      res.forEach((node) => {
        node.type = 'folder'
      })
      // 支持流程模型的model
      const tree = this.createModelTreeNode(res || [])
      const list = this.modelListFlat(res || [])
      return {
        tree,
        list
      }
    },

    modelListFlat (tree = []) {
      const list = []
      tree.forEach(folder => {
        if (folder.modelResults && folder.modelResults.length) {
          list.push(...folder.modelResults)
        }
      })
      return list
    },

    createModelTreeNode (tree) {
      return lodash.cloneDeep(tree).map((node) => {
        node.disabled = node.type === 'folder'
        if (node.modelResults) {
          node.id = 'folder' + node.id
          node.children = node.modelResults.filter(
            (item) => item.supportProcess
          )
          node.children.forEach((item) => {
            item._id = item.id
            item.name = `${item.name}(${item.code})`
          })
        }
        return node
      })
    }
  }
}
</script>

<style lang="scss">
.property-panel {
  padding: 20px;
  .title{
    font-weight: bold;
    margin-bottom: 10px;
  }

  // reset element css
  .el-form--label-top .el-form-item__label {
    padding: 0;
    color: #99a9bf;;
  }

  .tab-table .el-form-item {
      margin-bottom: 16px;
  }
  .node-name {
    border-bottom: 1px solid #ccc;
    padding: 0 0 10px 20px;
    margin-bottom: 10px;
    font-size: 16px;
    font-weight: bold;
    color: #444;
  }
}
</style>
